﻿using EAS.Content.Buffs;
using EAS.Content.Items;
using EAS.Content.Projectiles;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.DataStructures;
using Terraria.ID;
using Terraria.ModLoader;

namespace EAS.Common.Players
{
    public class AccPlayer : ModPlayer
    {
        public bool hasAmulet;
        public bool bloodFlame;
        public bool boneBracersEffect;
        public bool magicRuneEffect;
        public bool probes;
        public bool frozenStone;
        public bool IchorStone;
        public bool curseStone;
        public static bool DevilMinion;
        public static readonly int DashDown = 0;
        public static readonly int DashUp = 1;
        public static readonly int DashRight = 2;
        public static readonly int DashLeft = 3;
        public int DashDir = -1;
        public bool DashActive;
        public int DashDelay = AccPlayer.MAX_DASH_DELAY;
        public int DashTimer = AccPlayer.MAX_DASH_TIMER;
        public readonly float DashVelocity = 15f;
        public static readonly int MAX_DASH_DELAY = 10;
        public static readonly int MAX_DASH_TIMER = 10;
        public bool oilBarrel;
        public bool wearingForceField;
        public bool EyeOfFury;
        public bool ObsidianScarf;
        public bool VinesGloves;
        public bool KingSlimeCrown;
        public bool Sunflower;
        public bool lifeFlower;
        public bool BleedingHeart;
        public bool HeartOfOcean;
        public bool BoilingWaterBottle;
        public bool CactusCushion;
        public override void ResetEffects()
        {
            hasAmulet = false;
            bloodFlame = false;
            boneBracersEffect = false;
            magicRuneEffect = false;
            probes = false;
            frozenStone = false;
            IchorStone = false;
            curseStone = false;
            DevilMinion = false;
            oilBarrel = false;
            wearingForceField = false;
            EyeOfFury = false;
            ObsidianScarf = false;
            VinesGloves = false;
            KingSlimeCrown = false;
            lifeFlower = false;
            BleedingHeart = false;
            HeartOfOcean = false;
            BoilingWaterBottle = false;
            CactusCushion = false;
            Sunflower = false;
            bool dashAccessoryEquipped = false;
            for (int i = 3; i < 8 + Player.extraAccessorySlots; i++)
            {
                Item item = Player.armor[i];
                if (item.type == ModContent.ItemType<ObsidianScarf>())
                {
                    dashAccessoryEquipped = true;
                }
                else if (item.type == ItemID.EoCShield || item.type == ItemID.MasterNinjaGear || item.type == ItemID.Tabi)
                {
                    return;
                }
            }
            if (!dashAccessoryEquipped || Player.setSolar || Player.mount.Active || DashActive)
            {
                return;
            }
            if (Player.controlDown && Player.releaseDown && Player.doubleTapCardinalTimer[DashDown] < 15)
            {
                DashDir = DashDown;
            }
            else if (Player.controlUp && Player.releaseUp && Player.doubleTapCardinalTimer[DashUp] < 15)
            {
                DashDir = DashUp;
            }
            else if (Player.controlRight && Player.releaseRight && Player.doubleTapCardinalTimer[DashRight] < 15)
            {
                DashDir = DashRight;
            }
            else
            {
                if (!Player.controlLeft || !Player.releaseLeft || Player.doubleTapCardinalTimer[DashLeft] >= 15)
                {
                    return;
                }
                DashDir = DashLeft;
            }
            DashActive = true;
        }
        public override void UpdateDead()
        {
            hasAmulet = false;
            bloodFlame = false;
            boneBracersEffect = false;
            magicRuneEffect = false;
            probes = false;
            frozenStone = false;
            IchorStone = false;
            curseStone = false;
            DevilMinion = false;
            oilBarrel = false;
            wearingForceField = false;
            EyeOfFury = false;
            ObsidianScarf = false;
            VinesGloves = false;
            KingSlimeCrown = false;
            lifeFlower = false;
            BleedingHeart = false;
            HeartOfOcean = false;
            BoilingWaterBottle = false;
            CactusCushion = false;
            Sunflower = false;
        }
        public override void ModifyHurt(ref Player.HurtModifiers modifiers)
        {
            if (hasAmulet)
            {
                if (Main.rand.NextFloat() < 0.1f) 
                {
                    int damageReduction = 5;
                    if (modifiers.FinalDamage.Base >= damageReduction + 1)
                    {
                        modifiers.FinalDamage.Base -= damageReduction;
                    }
                    else
                    {
                        modifiers.FinalDamage.Base = 1; 
                    }
                    for (int i = 0; i < 5; i++)
                    {
                        Dust.NewDust(Player.position, Player.width, Player.height, DustID.Copper);
                    }
                }
            }
        }

        public override void DrawEffects(PlayerDrawSet drawInfo, ref float r, ref float g, ref float b, ref float a, ref bool fullBright)
        {
            if (bloodFlame)
            {
                Vector2 leftPosition = Player.position + new Vector2(-50, Player.height / 2);
                Vector2 rightPosition = Player.position + new Vector2(50, Player.height / 2);
                Dust dust = Dust.NewDustDirect(leftPosition, 0, 0, DustID.Crimson, Player.velocity.X, Player.velocity.Y, 100, default, 1.5f);
                dust.noGravity = true;
                Dust dust2 = Dust.NewDustDirect(rightPosition, 0, 0, DustID.Crimson, Player.velocity.X, Player.velocity.Y, 100, default, 1.5f);
                dust2.noGravity = true;
            }
        }
        public override void OnHitNPCWithItem(Item item, NPC target, NPC.HitInfo hit, int damageDone)
        {
            if (frozenStone && item.CountsAsClass(DamageClass.Melee))
            {
                target.AddBuff(44, 600, false);
            }
            if (IchorStone && item.CountsAsClass(DamageClass.Melee))
            {
                target.AddBuff(69, 600, false);
            }
            if (curseStone && item.CountsAsClass(DamageClass.Melee))
            {
                target.AddBuff(39, 600, false);
            }
            if (oilBarrel && item.CountsAsClass(DamageClass.Melee))
            {
                target.AddBuff(204, 240, false);
            }
        }
        public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone)
        {
            if (boneBracersEffect)
            {
                if (Main.rand.NextFloat() < 0.001f + (Player.statLifeMax2 * 0.001f) + (Player.statManaMax2 * 0.0001f) + (Player.luck * 0.005f))
                {
                    int healAmount = (int)(Player.statLifeMax2 * 0.05f);
                    int manaAmount = (int)(Player.statManaMax2 * 0.05f);
                    if (Player.statLife < Player.statLifeMax2)
                    {
                        Player.statLife += healAmount;
                        Player.HealEffect(healAmount);
                    }
                    else
                    {
                        Player.statMana += manaAmount;
                        Player.ManaEffect(manaAmount);
                    }
                }
            }
            if (bloodFlame) 
            {
                Player.statLife += 5;
                Player.HealEffect(5);
            }
        }
        public override void OnHitNPCWithProj(Projectile proj, NPC target, NPC.HitInfo hit, int damageDone)
        {
            if (frozenStone && proj.CountsAsClass(DamageClass.Melee))
            {
                target.AddBuff(44, 600, false);
            }
            if (IchorStone && proj.CountsAsClass(DamageClass.Melee))
            {
                target.AddBuff(69, 600, false);
            }
            if (oilBarrel && proj.CountsAsClass(DamageClass.Melee))
            {
                target.AddBuff(204, 180, false);
            }
            if (oilBarrel && proj.CountsAsClass(DamageClass.Ranged))
            {
                target.AddBuff(204, 180, false);
            }
            if (curseStone && proj.CountsAsClass(DamageClass.Melee))
            {
                target.AddBuff(39, 600, false);
            }
            if (magicRuneEffect && proj.CountsAsClass(DamageClass.Magic))
            {
                target.AddBuff(44, 600, false);
            }
        }
        public override void PostHurt(Player.HurtInfo info)
        {
            if (lifeFlower && Player.QuickHeal_GetItemToUse() != null && Player.statLife + Player.QuickHeal_GetItemToUse().healLife < Player.statLifeMax2)
            {
                Player.QuickHeal();
            }
        }
        public override void PreUpdate()
        {
            if (DevilMinion && Player.ownedProjectileCounts[ModContent.ProjectileType<DevilMinion>()] < 1)
            {
                Projectile.NewProjectile(null, Player.position, Vector2.Zero, ModContent.ProjectileType<DevilMinion>(), 50, 5f, Player.whoAmI);
            }           
        }
        public override void PostUpdate()
        {
            if (BleedingHeart)
            {
                if (Main.rand.NextBool(10))
                {
                    int damage = (int)(Player.GetWeaponDamage(Player.HeldItem) * 0.05f);
                    Player.statLife += damage;
                    Vector2 direction = Player.DirectionTo(Main.MouseWorld);
                    for (int i = 0; i < 100; i++)
                    {
                        Vector2 position = Player.Center + direction * i;
                        foreach (NPC npc in Main.npc)
                        {
                            if (npc.active && npc.Hitbox.Intersects(new Rectangle((int)position.X, (int)position.Y, 1, 1)))
                            {
                                NPC target = npc;
                                if (target.friendly || target.townNPC)
                                {
                                    return;
                                }
                                if (target.life <= target.lifeMax * 0.47f)
                                {
                                    target.AddBuff(ModContent.BuffType<BleedingDebuff>(), 300);
                                }
                                break;
                            }
                        }
                    }
                }
            }
            if (HeartOfOcean)
            {
                Player.AddBuff(ModContent.BuffType<DolphinBuff>(), 2);
                Player.accFlipper = true;
                Player.breathMax = 200;
                if (Player.wet)
                {
                    Lighting.AddLight(Player.position, 0.5f, 0.5f, 1f);
                }

            }
            if (BoilingWaterBottle)
            {
                Dust.NewDust(Player.position, Player.width, Player.height, DustID.Water, 0f, 0f, 100, default, 1f);
                bool isSubmerged = Player.wet;
                if (isSubmerged)
                {
                    Player.moveSpeed += 0.2f;
                    Player.statDefense += 5;
                    Player.breathMax += 30;
                }
            }
            if (CactusCushion)
            {
                Player.thorns = 0.4f;
            }
            if (Sunflower)
            {
                if (Player.ZoneForest)
                {
                    Player.moveSpeed += 0.15f;
                    Player.lifeRegen += 2;
                    Player.luck += 0.05F;
                }
            }
            if (KingSlimeCrown)
            {
                if (Player.ownedProjectileCounts[ModContent.ProjectileType<GelProjectile>()] < 4)
                {
                    for (int v = 0; v < 4; v++)
                    {
                        Projectile.NewProjectile(Player.GetSource_Accessory(null), Player.Center, Vector2.Zero, ModContent.ProjectileType<GelProjectile>(), 0, 0f, Main.myPlayer, v);
                    }
                }

            }
            if (VinesGloves)
            {
                if (Player.ownedProjectileCounts[ModContent.ProjectileType<Thorn>()] < 6 && Main.myPlayer == Player.whoAmI)
                {
                    bool[] tentaclesPresent = new bool[6];
                    for (int i = 0; i < Main.maxProjectiles; i++)
                    {
                        Projectile projectile = Main.projectile[i];
                        if (projectile.active && projectile.type == ModContent.ProjectileType<Thorn>() && projectile.owner == Main.myPlayer && projectile.ai[1] >= 0f && projectile.ai[1] < 6f)
                            tentaclesPresent[(int)projectile.ai[1]] = true;
                    }

                    for (int i = 0; i < 6; i++)
                    {
                        if (!tentaclesPresent[i])
                        {
                            int damage = 40;
                            damage = 40;

                            var source = Player.GetSource_FromThis(null);
                            Vector2 vel = new Vector2(Main.rand.Next(-13, 14), Main.rand.Next(-13, 14)) * 0.25f;
                            Projectile.NewProjectile(source, Player.Center, vel, ModContent.ProjectileType<Thorn>(), damage, 8f, Main.myPlayer, Main.rand.Next(120), i);
                        }
                    }
                }
            }
            if (ObsidianScarf)
            {
                Player.moveSpeed += 0.02f;
                Player.lavaRose = true;
            }
            if (EyeOfFury)
            {
                Player.AddBuff(ModContent.BuffType<StoneGiantBuff>(), 2);
                Player.GetCritChance(DamageClass.Melee) += 10;
                Player.GetCritChance(DamageClass.Ranged) += 10;
                Player.GetCritChance(DamageClass.Magic) += 10;
                Player.GetCritChance(DamageClass.Summon) += 10;
            }
            if (wearingForceField)
            {
                for (int k = 0; k < 180; k++)
                {
                    Dust.NewDustPerfect(Player.Center + new Vector2(100f, 0f).RotatedBy((double)MathHelper.ToRadians(k * 2), default), 20, null, 0, new Color(255, 255, 255), 0.25f).noGravity = true;
                }
                for (int projectile_iteration = 0; projectile_iteration < 1000; projectile_iteration++)
                {
                    Projectile projectile = Main.projectile[projectile_iteration];
                    for (int npc_iteration = 0; npc_iteration < 200; npc_iteration++)
                    {
                        NPC npc = Main.npc[npc_iteration];
                        if (projectile.active && projectile.hostile && projectile.damage <= 20 && projectile.Distance(Player.Center) <= 100f || npc.type == NPCID.WaterSphere && npc.Distance(Player.Center) <= 100f || npc.type == NPCID.ChaosBall && npc.Distance(Player.Center) <= 100f)
                        {
                            projectile.Kill();
                            for (int dustTimes = 0; dustTimes <= 3; dustTimes++)
                            {
                                Dust.NewDust(projectile.Center, projectile.width, projectile.height, DustID.Electric, 0f, 0f, 0, default, 1f);
                            }
                        }
                    }
                }
            }
            if (wearingForceField)
            {
                for (int l = 0; l < 180; l++)
                {
                    Dust.NewDustPerfect(Player.Center + new Vector2(125f, 0f).RotatedBy((double)MathHelper.ToRadians(l * 2), default), 20, null, 0, new Color(255, 255, 255), 0.25f).noGravity = true;
                }
                for (int projectile_iteration2 = 0; projectile_iteration2 < 1000; projectile_iteration2++)
                {
                    Projectile projectile2 = Main.projectile[projectile_iteration2];
                    for (int npc_iteration2 = 0; npc_iteration2 < 200; npc_iteration2++)
                    {
                        NPC npc2 = Main.npc[npc_iteration2];
                        if (projectile2.active && projectile2.hostile && projectile2.damage <= 20 && projectile2.Distance(Player.Center) <= 125f)
                        {
                            projectile2.Kill();
                            Dust.NewDust(projectile2.Center, projectile2.width, projectile2.height, DustID.Electric, 0f, 0f, 0, default, 1f);
                        }
                    }
                }
            }
        }
    }
}
